#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <pthread.h>
#include "../include/common.h"
#include "../include/client_io.h"


#define SERVER_PORT 9090
#define SERVER_ADDR "127.0.0.1"

static int sockfd = -1;
char buffer[MAXSIZE];
int user_id = -1;
int stop = 0;

int connect_server(int argc, char *argv[]) {
	struct sockaddr_in server_addr; /*定义服务器端套接口数据结构server_addr */
	struct hostent *host;			/*定义一个hostent结构的指针 */
	int portnumber;
	if (argc != 3)
	{
		fprintf(stderr, "Usage:%s hostname portnumber\a\n", argv[0]);
		exit(1);
	}
	if ((host = gethostbyname(argv[1])) == NULL) /*通过域名或主机名得到包含地址的hostent指针 */
	{											 /*获得命令行的第二个参数-主机名*/
		fprintf(stderr, "Gethostname error\n");
		exit(1);
	}
	if ((portnumber = atoi(argv[2])) < 0)
	{ /*获得命令行的第三个参数--端口号，atoi()把字符串转换成整型数*/
		fprintf(stderr, "Usage:%s hostname portnumber\a\n", argv[0]);
		exit(1);
	}
	/* 客户程序开始建立 sockfd描述符 */
	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		fprintf(stderr, "Socket Error:%s\a\n", strerror(errno));
		exit(1);
	}
	/*客户程序填充服务端的资料*/
	bzero(&server_addr, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(portnumber);
	server_addr.sin_addr = *((struct in_addr *)host->h_addr);
	/*客户程序发起连接请求*/
	if (connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1)
	{
		fprintf(stderr, "Connect Error:%s\a\n", strerror(errno));
		exit(1);
	}
	return 0;
}

void handle_reply(Reply *r) {

	size_t len = 0;

	if (r->err == ERRNOTLOGGEDIN) {
		format_err("您还未登陆\n");

	} else if (r->err == ERRNOTFOUND) {
		format_err("未查找到商品信息\n");

	} else if (r->err == ERRZERO) {
		format_err("商品库存不足\n");	
	
	} else if (r->err == SUCCESS) {
		switch (r->type) {

			case BUY:
				{
					len = strlen(r->data);
					if (r->data[len - 1] != '\n' && len + 2 <= MAX_DATA) {
						strncpy(r->data + len, "\n", 2);
					}
					format_print("---------购买信息----------\n");
					format_print(r->data);
					format_print("--------------------------\n");
					char buffer[100];
					snprintf(buffer, 100, "您购买的商品总金额为: %d\n", r->total_price);
					format_print(buffer);
				}
				break;

			case SELL:
				format_print("成功\n");
				break;

			case VIEW:
				len = strlen(r->data);
				if (r->data[len - 1] != '\n' && len + 2 <= MAX_DATA) {
					strncpy(r->data + len, "\n", 2);
				}
				format_print("---------商品信息----------\n");
				format_print(r->data);
				format_print("--------------------------\n");
				break;

			case LIST:
				len = strlen(r->data);
				if (r->data[len - 1] != '\n' && len + 2 <= MAX_DATA) {
					strncpy(r->data + len, "\n", 2);
				}
				format_print("---------商品列表----------\n");
				format_print(r->data);
				format_print("--------------------------\n");
				break;

			case RECORDS:
				len = strlen(r->data);
				if (r->data[len - 1] != '\n' && len + 2 <= MAX_DATA) {
					strncpy(r->data + len, "\n", 2);
				}
				format_print("---------买卖记录----------\n");
				format_print(r->data);
				format_print("--------------------------\n");
				break;

			default:
				break;
		}
	}
}


void *readsock(void *args) {

	Reply rep;

	while(1) {

		int n = recv(sockfd, &rep, MAXSIZE, 0);
		if (n == 0) {
            printf("服务端关闭连接\n");
            break; 
        } else if (n < 0) {
            if (errno == EINTR) continue;
			printf("errno = %d", errno); 
            perror("recv 错误");
            break; 
        }

		if (rep.type == QUIT) {
			break;
		}
		if (rep.type == LOGIN && rep.err == SUCCESS) {
			user_id = rep.user_id;
			continue;
		}
		handle_reply(&rep);
	}
	exit(0);
}

int main(int argc, char *argv[]) {

	if (connect_server(argc, argv) != 0) return 1;

	pthread_t read_thread;
	pthread_create(&read_thread, NULL, readsock, (void *)&sockfd);
	Command	cmd;
	printPrompt();
	while (!stop)
	{
		memset(&cmd, 0x00, sizeof(Command));
		cmd.user_id = user_id;
		format_print("> ");
		if (Fgets(buffer, sizeof(buffer)) < 0) {
			continue;
		}
		if (strcmp(buffer, "0") == 0) {
			cmd.type = QUIT;
			stop = 1;
		}
		else if (strcmp(buffer, "1") == 0) {
			if (user_id != -1) {
				format_err("请勿重复登陆\n");
				continue;
			}
			if (get_login_args(&cmd) < 0) {
				continue;
			}
		}
		else if (strcmp(buffer, "2") == 0) {
			if (get_buy_args(&cmd) < 0) {
				continue;
			}
		}
		else if (strcmp(buffer, "3") == 0) {
			if (get_sell_args(&cmd) < 0) {
				continue;
			}
		}
		else if (strcmp(buffer, "4") == 0) {
			if (get_view_args(&cmd) < 0) {
				continue;
			}
		}
		else if (strcmp(buffer, "5") == 0) {
			cmd.type = LIST;
		}
		else if (strcmp(buffer, "6") == 0) {
			cmd.type = RECORDS;
		}
		else if (strcmp(buffer, "7") == 0) {
			user_id = -1;
			format_print("已登出");
			continue;
		}
		else {
			printPrompt();
			continue;
		}


		if (send(sockfd, &cmd, MAXSIZE, 0) < 0) {
			perror("socket error.\n");
			break;
		}
		usleep(1000);
	}
	
	pthread_join(read_thread, NULL);
	close(sockfd);
	return 0;
}

